﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.Security.Permissions;



namespace System.Collections.Generic.Sync
{
    public class RecycleList<T> : IEnumerable<T>
    {
        System.Threading.ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
        IRecycleNode<T> _Bottom, _Top;
        //public IRecycleNode<T> Top
        //{
        //    get
        //    {
        //        _lock.EnterReadLock();
        //        var t = _Top;
        //        _lock.ExitReadLock();
        //        return t;
 
        //    }
        //}

        public void Clear()
        {
            _lock.EnterWriteLock();
            _Top = null;
            _lock.ExitWriteLock();
        }

        public void StackOn( IRecycleNode<T>  newOne)
        {
            _lock.EnterWriteLock ();
            newOne.Lower = newOne.Higher = null;
            if (_Top != null)
            {
                _Top.Higher = newOne;
                newOne.Lower = _Top;
                _Top = newOne;
          
            }
            else
            {                
                 _Top =newOne  ;
                 _Bottom = _Top;
            }
            newOne.TimeStamp = DateTime.Now;
            _lock.ExitWriteLock();
        }

        public void RecycleFromButtom(Func<IRecycleNode<T>, bool> RecycleCondition)
        {
            var bn = _Bottom;
            //if (_Bottom == null) _Bottom = ;
            var bh = bn;
            if (bh != null) bh = bh.Higher;
            while (bn != null & bh != null)
            {
                if (RecycleCondition(bn))
                {                
                        bh.Lower = null;
                }
                _Bottom = bh;
                bn = _Bottom;
                bh = bn.Higher;

            }
            
        }

        #region IEnumerable<T> Members
        public IEnumerator<T> GetEnumerator()
        {
            return new RecycleListEnumerator<T>(_Top);
        }

        #endregion
    
        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new RecycleListEnumerator<T>(_Top);
        }

        #endregion


    
    }

    public interface IRecycleNode<T>
    {
        IRecycleNode<T> Lower { get; set; }
        IRecycleNode<T> Higher { get; set; }
        T Value { get; set; }
        DateTime TimeStamp
        {
            get;
            set;
        }
    }

    public class RecycleListEnumerator<T> : IEnumerator<T>
    {
        IRecycleNode<T> _beginNode;
        IRecycleNode<T> _currentNode;
     public      RecycleListEnumerator(IRecycleNode<T> beginNode)
        {
            _beginNode = _currentNode = beginNode;
        }
        #region IEnumerator<T> Members

        public T Current
        {
            get { return _currentNode.Value; }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            _beginNode = null;
            _currentNode = null;
        }
        #endregion

        #region IEnumerator Members

        object IEnumerator.Current
        {
            get { return Current; }
        }
        private bool startedFlag=false ;
        public bool MoveNext()
        {
            if (!startedFlag) 
            {
                startedFlag =true ;
                return (_beginNode != null);

            };
            var cl = _currentNode.Lower;
            if (cl != null)
            {
                _currentNode = cl;
                return true;
            }
            else
                return false;
        }

        public void Reset()
        {
            _currentNode = _beginNode;
        }

        #endregion
    }

}
